package mqtt

import (
	"encoding/json"
	"regexp"
	"strings"
	"t11Lib/t11Errors"
	"t11Lib/t11Log"
	"t11Lib/t11Model"
	"t11Lib/t11Util"
	"亚太-iot-服务器/biz"
	"亚太-iot-服务器/biz/mqtt/internal"
	"亚太-iot-服务器/models"
)

var AccountBiz internal.AccountBiz
var mqTitleRegex = regexp.MustCompile(`^/\d{1,3}/(fromDev)|(toDev)/[a-fA-F0-9]{12}$`)
var ClientToIdx = internal.ClientIdToInt

type mqHub struct {
	*internal.GatewayHub
}

func (self *mqHub) msgHandler(msg *biz.MqMsg) t11Errors.T11Error {
	//根据消息的topic判断客户端Id
	if !mqTitleRegex.MatchString(msg.Topic) {
		return t11Errors.Newf("非法的数据包：msg = %v", msg)
	}
	gatewayId := strings.Split(msg.Topic, "/")[3]
	ret := &biz.MqttMsg{}
	if err := json.Unmarshal([]byte(msg.Data), ret); err != nil {
		return t11Errors.Newf("mqtt数据包格式不正确，msg = %v", msg)

	}
	if gatewayId != ret.GatewayId {
		return t11Errors.Newf("非法的gatewayId：", t11Errors.New("非法的数据"))
	}
	switch ret.Cmd {
	case biz.CmdFromGateway:
		return self.handleGatewayCmd(ret)
	case biz.CmdFromDev:
		self.SetGatewayOnlineStatus(true, gatewayId)
		return self.handleDevCmd(ret)
	default:
		return t11Errors.Newf("非法的mqtt数据，gatewayId = %v, msg = %v", gatewayId, ret)
	}
}

func (self *mqHub) SendToWs(body *biz.MqttMsg, wxUsers []*models.JwtToken) {
	for _, user := range wxUsers {
		//单个发送失败忽略之
		if e := biz.WsMsgSender.SendMsg(user, body); e != nil {
			t11Log.Debuglnf("e = %v", e)
		}
	}
}

func (self *mqHub) redirectToWs(body *biz.MqttMsg, f biz.MqttMsgHandlerFunc) t11Errors.T11Error {
	//将相关信息转发给微信用户
	dbConn := t11Model.NewDbConn()

	tokens, err := models.UserDeviceDao.GetTokensByDeviceId(dbConn, body.DevId)
	if err != nil {
		return err
	}

	err = f(dbConn, body)
	if err != nil {
		return err
	}

	t11Log.Debuglnf("tokens = %v", tokens)
	// todo 推送功能暂时未实现
	for _, token := range tokens {
		//单个发送失败忽略之
		if e := biz.WsMsgSender.SendMsg(token, body); e != nil {
			t11Log.Debuglnf("e = %v", e)
		}
	}
	return nil
}

//具体设备的命令处理函数
func (self *mqHub) handleDevCmd(msg *biz.MqttMsg) t11Errors.T11Error {
	var conn = t11Model.NewDbConn()
	var _data []byte
	if msg.Data != "" {
		if data, e := t11Util.HexStringToBytes(msg.Data); e != nil {
			return e
		} else {
			_data = data
		}
	}
	switch msg.SubCmd {
	case biz.SubCmdFromDev_SetKv:
		return biz.DevBiz.SetKv(conn, msg, _data)
	case biz.SubCmdFromDev_UploadLog:
		return biz.DevBiz.UploadLog(conn, msg, _data)
	case biz.SubCmdFromDev_CmdFromDev:
		return biz.DevBiz.CmdFromDev(conn, msg, _data)
	default:
		return t11Errors.New("非法的命令")
	}
}

//处理CmdFromClient的命令
func (self *mqHub) handleGatewayCmd(body *biz.MqttMsg) t11Errors.T11Error {

	t11Log.Debuglnf("收到网关命令：data = %v", body.Data)
	switch body.SubCmd {
	case biz.SubCmdFromGw_Online:
		self.SetGatewayOnlineStatus(true, body.GatewayId)
		return nil
	case biz.SubCmdFromGw_Offline:
		self.SetGatewayOnlineStatus(false, body.GatewayId)
		return nil
	case biz.SubCmdFromGw_PassThrough:
		return biz.DevBiz.HandleGatewayCmdPassThrough(body)
	case biz.SubCmdFromGw_DevAddSuccess:
		return self.redirectToWs(body, biz.DevBiz.HandleGatewayCmdDevAddSuccess)
	case biz.SubCmdFromGw_DevAddCanceled:
		return self.redirectToWs(body, biz.DevBiz.HandleGatewayCmdDevAddCanceled)
	case biz.SubCmdFromGw_DelDevSuccess:
		return self.redirectToWs(body, biz.DevBiz.HandleGatewayCmdDelDevSuccess)
	default:
		return t11Errors.New("非法的命令")
	}
}

var gwMqttManager = func() *mqHub {
	l := internal.CreateMqttThread()
	gm := internal.NewGatewayManager(l)
	ret := &mqHub{GatewayHub: gm}
	l.RegisterMsgHandler(ret.msgHandler)
	biz.MqttMsgSender = ret
	return ret
}()
